#include <iostream>
#include <string>
#include <vector>
#include "Util.hpp"

namespace protocol_ns
{
    #define SEP " "
    #define SEP_LEN strlen(SEP)

    class Request
    {
    public:
        Request() {};
        Request(int x, int y, char op) :_x(x), _y(y), _op(op)
        {}
        bool Serialize(std::string* outStr)
        {
            *outStr = "";
            std::string x_string = std::to_string(_x);
            std::string y_string = std::to_string(_y);
            *outStr = x_string + SEP + y_string + SEP + _op;

            return true;
        }
        bool Deserialize(const std::string& inStr)
        {
            std::vector<std::string> result;
            Util::StringSplit(inStr, SEP, &result);
            if (result.size() != 3) return false;
            if (result[1].size() != 1) return false;
            _x = Util::toInt(result[0]);
            _y = Util::toInt(result[2]);
            _op = result[1][0];
            return true;
        }
        ~Request()
        {}
    public:
        int _x;
        int _y;
        char _op;
    };

    class Response
    {
    public:
        Response() {}
        Response(int result, int code) :_result(result), _code(code) 
        {}

        bool Serialize(std::string* outStr)
        {
            *outStr = "";
            std::string res_string = std::to_string(_result);
            std::string code_string = std::to_string(_code);
            *outStr = res_string + SEP + code_string;

            return true;
        }
        bool Deserialize(const std::string& inStr)
        {
            std::vector<std::string> result;
            Util::StringSplit(inStr, SEP, &result);
            if (result.size() != 2) return false;
            _result = Util::toInt(result[0]);
            _code = Util::toInt(result[1]);
            return true;
        }

        ~Response() {}
    public:
        int _result;
        int _code;
    };
}